package campus.aiit.ssl.manage.custom;

import campus.aiit.ssl.domain.param.BadResult;
import campus.aiit.ssl.domain.param.BadStatusEnum;
import campus.aiit.ssl.manage.custom.dao.DaoResultException;
import org.apache.ibatis.binding.BindingException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.support.MissingServletRequestPartException;

import java.net.SocketException;

/**
 * Application Wide Controllers Exceptions Handlers
 *
 * @author ihaokun
 * @date 2019/11/30 17:55
 */
@RestControllerAdvice
public class ControllersAdvice {

  @ExceptionHandler(Exception.class)
  public String appWideExceptionHandler(Exception e) {
    e.printStackTrace();
    return new BadResult(BadStatusEnum.BASE_EXCEPTION, e.getMessage()).toString();
  }

  // In Param Exceptions Handlers
  // @RequestParam 注解抛出异常
  @ExceptionHandler(MissingServletRequestParameterException.class)
  public String requireParam(MissingServletRequestParameterException e) {
    e.printStackTrace();
    return new BadResult(BadStatusEnum.IN_PARAM_EXCEPTION, "必需参数缺失").toString();
  }
  // @RequestPart 注解抛出异常
  @ExceptionHandler(MissingServletRequestPartException.class)
  public String requirePart(MissingServletRequestPartException e){
    e.printStackTrace();
    return new BadResult(BadStatusEnum.IN_PARAM_EXCEPTION, "MultiPart缺失").toString();
  }
  // @RequestBody 注解抛出异常
  @ExceptionHandler(HttpMessageNotReadableException.class)
  public String requireBody(HttpMessageNotReadableException e){
    e.printStackTrace();
    return new BadResult(BadStatusEnum.IN_PARAM_EXCEPTION, "传参不符合JSON格式").toString();
  }
  // @PathVariable 注解抛出异常
  @ExceptionHandler(MissingPathVariableException.class)
  public String requierPathVariable(MissingPathVariableException e){
    e.printStackTrace();
    return new BadResult(BadStatusEnum.IN_PARAM_EXCEPTION, "路径变量缺失").toString();
  }
  // JSR-303 Validation Exception
  @ExceptionHandler(MethodArgumentNotValidException.class)
  public String validationFailed(MethodArgumentNotValidException e){
    e.printStackTrace();
    return new BadResult(BadStatusEnum.IN_PARAM_EXCEPTION, "参数验证失败").toString();
  }

  // DAO Exceptions
  @ExceptionHandler(DataIntegrityViolationException.class)
  public String springDaoException(DataIntegrityViolationException e){
    System.err.println("Maybe database index restrict cause");
    e.printStackTrace();
    return new BadResult(BadStatusEnum.DAO_PROCESS_EXCEPTION, "破坏数据库约束完整性").toString();
  }
  // DAO(MyBatis) Exceptions Handlers
  @ExceptionHandler(BindingException.class)
  public String myBatisBindingException(BindingException e) {
    e.printStackTrace();
    return new BadResult(BadStatusEnum.BINDING_EXCEPTION, "MyBatis参数处理异常").toString();
  }
  @ExceptionHandler(DuplicateKeyException.class)
  public String daoProcessException(DuplicateKeyException e) {
    e.printStackTrace();
    return new BadResult(BadStatusEnum.DAO_PROCESS_EXCEPTION, "重复数据").toString();
  }

  // User-Defined Exceptions Handlers
  @ExceptionHandler(DaoResultException.class)
  public String daoResultException(DaoResultException e) {
    e.printStackTrace();
    return new BadResult(BadStatusEnum.DAO_RESULT_EXCEPTION, e.getMessage()).toString();
  }
  @ExceptionHandler(CsvTemplateException.class)
  public String CsvException(CsvTemplateException e){
    e.printStackTrace();
    return new BadResult(BadStatusEnum.SERVICE_EXCEPTION, e.getMessage()).toString();
  }
  @ExceptionHandler(SelectNpeException.class)
  public String selectNpe(SelectNpeException e){
    e.printStackTrace();
    return new BadResult(BadStatusEnum.DAO_RESULT_EXCEPTION, e.getLocalizedMessage()).toString();
  }

  // Network Exceptions
  @ExceptionHandler(SocketException.class)
  public String socketException(SocketException e){
    e.printStackTrace();
    return new BadResult(BadStatusEnum.SERVICE_EXCEPTION, e.getMessage()).toString();
  }
}